package auth

import (
	"errors"
	"fmt"

	"gitee.com/micro-plat/sas/sas/modules/auth/conf"
	"gitee.com/micro-plat/sas/sas/modules/const/enum"
	"gitee.com/micro-plat/sas/sas/modules/secret"
	per "gitee.com/micro-plat/sas/sas/modules/util/permission"

	"github.com/micro-plat/lib4go/errs"
	"github.com/micro-plat/lib4go/types"
)

//IAuth 接口
type IAuth interface {
	SingleAuth(input map[string]interface{}, conf *conf.AuthConfig, type1 string) (err error)
	MultiAuth(input map[string]interface{}, conf *conf.AuthConfig, type1, type2 string) (data map[string]interface{}, err error)
	DynamicAuth(input map[string]interface{}, conf *conf.AuthConfig, type1, type2 string) (data map[string]interface{}, err error)
}

//Auth 对象
type Auth struct{}

//NewAuth 创建对象
func NewAuth() *Auth {
	return &Auth{}
}

//check 检查类型及配置
func (a *Auth) check(input map[string]interface{}, rConf *conf.AuthConfig, type1, type2 string, authType int) (euid, signName, encodeKey string, err error) {
	//检查类型
	if err = checkType(type1, type2, authType); err != nil {
		return
	}

	//检查配置,获取uid
	return rConf.Check(input, authType)
}

//getSecret 获取签名密钥及解密密钥
func (a *Auth) getSecret(type1, type2, euid, encodeKey string, authType int) (signKey, signRsaType, decryptKey, decryptRsaType string, err error) {

	//获取密钥信息
	info, err := secret.GetSecretCache(euid)
	if err != nil {
		return
	}

	//检查签名类型、解密类型权限
	if err = a.checkPermission(info, type1, type2, authType); err != nil {
		return
	}

	//获取签名密钥
	signKey, signRsaType, err = getSignKey(info, type1, encodeKey, authType)
	if err != nil {
		return
	}

	//获取解密密钥
	decryptKey, decryptRsaType, err = getDecryptKey(info, type2, authType, signKey)
	return
}

//checkPermission 检查签名、解密类型权限
func (a *Auth) checkPermission(data types.XMap, type1, type2 string, authType int) error {
	if authType != enum.Dynamic && !per.Check(data.GetInt("status"), enum.GetValueByName(type1)) {
		return errs.NewError(enum.ERR_NotSupport, fmt.Errorf("该签名类型(%s)未开通", type1))
	}
	if authType == enum.Multi && !per.Check(data.GetInt("status"), enum.GetValueByName(type2)) {
		return errs.NewError(enum.ERR_NotSupport, fmt.Errorf("该签名类型(%s)未开通", type2))
	}
	if authType == enum.Dynamic && data.GetFloat64("expire_time") < 0 {
		return errors.New("RSA密钥已过期")
	}
	return nil
}
